

import re
# 检查表达式合法性
def check_expression(string):
    check_result  = True
    # 括弧是否匹配
    if not string.count("(") == string.count(")"):
        print("表达式错误，括号未闭合")
        check_result=False
    if re.findall('[a-z]',string.lower()):
        print('表达式有非法字符')
        check_result = False
    return check_result


#格式化字符串
def format_string(string):
    string = string.replace(' ','')
    string = string.replace('--','+')
    string = string.replace('-+','-')
    string = string.replace('++','+')
    string = string.replace('+-','-')
    string = string.replace('*+','*')
    string = string.replace('/+','/')
    return string

# 计算乘除法  (30+6*2+9/3)
def calc_mul_div(string):
    # regular = '\d+\.{0,}\d{0,}[\*\/][\-]{0,}\d+\.{0,}\d{0}'
    regular = '[\-]?\d+\.?\d*([*/]|\*\*)[\-]?\d+\.?\d*'
    # ret1 = re.search('\d+\.?\d*   [*/]  \d+\.?\d*',s)
    #如果还能找到乘除表达式
    while re.findall(regular,string):
        #  获取表达式
        expression = re.search(regular,string).group()

        #  如果是乘法
        if expression.count("*")==1:
            # 获取要计算到两个数
            x,y = expression.split("*")
            # 计算结果
            mul_result = str(float(x)* float(y))
            # 将计算到表达式替换为计算结果值
            string = string.replace(expression, mul_result)
            # 格式化一下
            string = format_string(string)

        # 如果是除法
        if expression.count("/")==1:
            x,y = expression.split("/")
            div_result = str(float(x) / float(y))
            string = string.replace(expression , div_result)
            string = format_string(string)

        if expression.count('*')==2:
            x,y = expression.split('**')
            pow_result = 1
            for i in range(int(y)):
                pow_result *= int(x)
            string = string.replace(expression,str(pow_result))
            string = format_string(string)
    return string


def calc_add_sub(string):
    add_regular = '[\-]?\d+\.?\d*\+[\-]?\d+\.?\d*'
    sub_regular = '[\-]?\d+\.?\d*\-[\-]?\d+\.?\d*'

    #开始加法
    while  re.findall(add_regular,string):
        add_list = re.findall(add_regular,string)

        #如果是加法
        if add_list.count("+")==1:
            x,y = add_list.split("+")
            add_result = str(float(x) + float(y))
            string = string.replace(add_list, add_result)
        string = format_string(string)
    # 开始减法
    while re.findall(sub_regular,string):
        sub_list = re.findall(sub_regular,string)
        for sub_str in sub_list:
            numbers = sub_str.split("-")
            if len(numbers) == 3:
                result = 0
                for v in numbers:
                    if v:
                        result -= float(v)
            else:
                x,y = numbers
                result = float(x) - float(y)

            # 替换字符串
            string = string.repalce(sub_str,"+" + str(result))
        string = format_string(string)
    return string


if __name__ == "__main__":
    source = "1 - 2 * ( (60-30 +(-9-2-5-2*3-5/3-40*4/2-3/5+6*3) * (-9-2-5-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )"

    if check_expression(source):
        print("原数据:", source)
        print("eval result:", eval(source))
        # source = format_string(source)
        # print(source)
        while  source.count("(") > 0:
            #格式化  去括号，得到括号的字符串， 比如：（30+6/3）
            source = format_string(source)
            strs =  re.search('\(([/-]*\d+\.*\d*[\+\-\*/]+)+\d+\.*\d*\)',source).group()
            # 将括号的表达式进行乘除运算
            replace_str = calc_mul_div(strs)
            # 将运算结果再进行加减运算
            replace_str = calc_add_sub(replace_str) #[1,-1]
            # 将括号到字符串替换未计算结果，结果包含（），替换时去掉（） ［1:－1］
            source = format_string(source.replace(strs, replace_str[1:-1]))
        else:
            # 没有括号就到最后单一表达式
            # 计算乘除
            replace_str = calc_mul_div(source)
            # 计算加减
            replace_str = calc_add_sub(replace_str)
            source = source.replace(source, replace_str)
        print("my result: ", source.replace("+", ""))


